/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package com.atguigu.netty.source.echo2;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;

import java.util.concurrent.Callable;

/**
 * Handler implementation for the echo server.
 */
@Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    //group 就是充当业务线程池，可以将任务提交到该线程池
    //这里我们创建了16个线程
    private static final EventExecutorGroup GROUP = new DefaultEventExecutorGroup(16);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("EchoServerHandler thread = " + Thread.currentThread().getName());

        //按照原来的方法处理耗时任务
        //解决方案1：用户程序自定义普通任务
//        ctx.channel().eventLoop().execute(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(10 * 1000);
//                    //输出线程名
//                    System.out.println("EchoServerHandler execute thread = " + Thread.currentThread().getName());
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端2", CharsetUtil.UTF_8));
//            }
//        });
//
//        ctx.channel().eventLoop().execute(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(10 * 1000);
//                    //输出线程名
//                    System.out.println("EchoServerHandler execute thread2 = " + Thread.currentThread().getName());
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端2", CharsetUtil.UTF_8));
//            }
//        });

        //将任务提交到group线程池
        GROUP.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                //接收客户端消息，传输内容转换为字符串的过程，ByteBuf -> String
                ByteBuf buf = (ByteBuf) msg;//转换为buf
                byte[] bytes = new byte[buf.readableBytes()];//创建传过来内容长度的字节数组
                buf.readBytes(bytes);//将buf读入到字节数组中
                String body = new String(bytes, "UTF-8");//将字节数组转化为字符串
                //休眠10s
                Thread.sleep(10000);
                System.out.println("GROUP.submit call Thread = " + Thread.currentThread().getName());
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端2", CharsetUtil.UTF_8));
                return null;
            }
        });

        GROUP.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                //接收客户端消息，传输内容转换为字符串的过程，ByteBuf -> String
                ByteBuf buf = (ByteBuf) msg;//转换为buf
                byte[] bytes = new byte[buf.readableBytes()];//创建传过来内容长度的字节数组
                buf.readBytes(bytes);//将buf读入到字节数组中
                String body = new String(bytes, "UTF-8");//将字节数组转化为字符串
                //休眠10s
                Thread.sleep(10000);
                System.out.println("GROUP.submit call Thread = " + Thread.currentThread().getName());
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端2", CharsetUtil.UTF_8));
                return null;
            }
        });

        GROUP.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                //接收客户端消息，传输内容转换为字符串的过程，ByteBuf -> String
                ByteBuf buf = (ByteBuf) msg;//转换为buf
                byte[] bytes = new byte[buf.readableBytes()];//创建传过来内容长度的字节数组
                buf.readBytes(bytes);//将buf读入到字节数组中
                String body = new String(bytes, "UTF-8");//将字节数组转化为字符串
                //休眠10s
                Thread.sleep(10000);
                System.out.println("GROUP.submit call Thread = " + Thread.currentThread().getName());
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端2", CharsetUtil.UTF_8));
                return null;
            }
        });

        System.out.println("go on");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }
}
